From fdfe556cc81c82929ddde245ab545412ec27e075 Mon Sep 17 00:00:00 2001 From: Debian Multimedia Maintainers Date: Thu, 6 Aug 2026 13:05:03 +0800 Subject: [PATCH] CVE-2024-38949, CVE-2024-38950: fix SDL OOB in dec265 display path Origin: upstream, https://github.com/strukturag/libde265/commit/4089de0845e0009e019be4ca5cbebaf2aee0a8ce Bug: https://github.com/strukturag/libde265/issues/460 Bug-Debian: https://bugs.debian.org/1074416 Applied-Upstream: 1.0.19 Heap buffer overflow in the dec265 SDL output on 4:4:4 streams (display444as420) and on mid-stream resolution changes. Gbp-Pq: Name CVE-2024-38949_CVE-2024-38950.patch --- dec265/dec265.cc | 21 ++++++++++++--------- dec265/sdl.cc | 39 ++++++++++++++++++++++++++++++++++++++- dec265/sdl.hh | 1 + 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/dec265/dec265.cc b/dec265/dec265.cc index ecf5d13..708408b 100644 --- a/dec265/dec265.cc +++ b/dec265/dec265.cc @@ -270,17 +270,20 @@ bool display_sdl(const struct de265_image* img) de265_chroma chroma = de265_get_chroma_format(img); + enum SDL_YUV_Display::SDL_Chroma sdlChroma; + switch (chroma) { + case de265_chroma_420: sdlChroma = SDL_YUV_Display::SDL_CHROMA_420; break; + case de265_chroma_422: sdlChroma = SDL_YUV_Display::SDL_CHROMA_422; break; + case de265_chroma_444: sdlChroma = SDL_YUV_Display::SDL_CHROMA_444; break; + case de265_chroma_mono: sdlChroma = SDL_YUV_Display::SDL_CHROMA_MONO; break; + default: assert(false); sdlChroma = SDL_YUV_Display::SDL_CHROMA_MONO; + } + if (!sdl_active) { sdl_active=true; - enum SDL_YUV_Display::SDL_Chroma sdlChroma; - switch (chroma) { - case de265_chroma_420: sdlChroma = SDL_YUV_Display::SDL_CHROMA_420; break; - case de265_chroma_422: sdlChroma = SDL_YUV_Display::SDL_CHROMA_422; break; - case de265_chroma_444: sdlChroma = SDL_YUV_Display::SDL_CHROMA_444; break; - case de265_chroma_mono: sdlChroma = SDL_YUV_Display::SDL_CHROMA_MONO; break; - } - - sdlWin.init(width,height, sdlChroma); + if (!sdlWin.init(width,height, sdlChroma)) return true; + } else { + if (!sdlWin.resize(width,height, sdlChroma)) return true; } int stride,chroma_stride; diff --git a/dec265/sdl.cc b/dec265/sdl.cc index eab1f8f..4211011 100644 --- a/dec265/sdl.cc +++ b/dec265/sdl.cc @@ -94,6 +94,43 @@ bool SDL_YUV_Display::init(int frame_width, int frame_height, enum SDL_Chroma ch return true; } +bool SDL_YUV_Display::resize(int frame_width, int frame_height, enum SDL_Chroma chroma) +{ + if (!mWindowOpen) { + return init(frame_width, frame_height, chroma); + } + + // SDL_PIXELFORMAT_YV12 requires even dimensions; init() rounds down to a + // multiple of 8, so we do the same here for consistency. + frame_width &= ~7; + frame_height &= ~7; + + if (frame_width == rect.w && frame_height == rect.h && mChroma == chroma) { + return true; + } + + // All chroma formats currently map to SDL_PIXELFORMAT_YV12 (we down-convert + // 4:2:2 and 4:4:4 ourselves), so the texture pixel format never changes. + // Only the texture dimensions and the window size need updating. + SDL_DestroyTexture(mTexture); + mTexture = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_YV12, + SDL_TEXTUREACCESS_STREAMING, + frame_width, frame_height); + if (!mTexture) { + printf("SDL: Couldn't recreate SDL texture: %s\n", SDL_GetError()); + mWindowOpen = false; + return false; + } + + SDL_SetWindowSize(mWindow, frame_width, frame_height); + + mChroma = chroma; + rect.w = frame_width; + rect.h = frame_height; + + return true; +} + void SDL_YUV_Display::display(const unsigned char *Y, const unsigned char *U, const unsigned char *V, @@ -247,7 +284,7 @@ void SDL_YUV_Display::display444as420(const unsigned char *Y, } uint8_t *startV = mPixels + (rect.h*mStride); - uint8_t *startU = startV + (rect.h*mStride/2); + uint8_t *startU = startV + (rect.h*mStride/4); for (int y=0;y